JS的同步非同步與Event Loop


Posted by Andy Tsai on 2020-04-12

同步非同步

有些人會說JavaScript是非同步的語言

不過要精確點說的話
JS是一個Single Thread(單執行緒)語言,一次只會做一件事,
所以JS本身是同步的語言,只是它具有非同步的特性

這是為了符合瀏覽器的使用情境,JS需要具有非同步的能力,而要達到非同步,靠的就是Event Loop

Event Loop運行機制

在JS執行緒中,有Heap和Stack,Heap是處理記憶體分配的地方,
而在Stack中,就是所有的JS任務,每個任務執行完後就會彈出Stack。

流程是,JS執行緒會逐一執行Stack內的程式,當遇到非同步行為時(例如setTimeout),它就會把它推到Event Queue(就是上圖中的Callback Queue)裡,然後等Stack裡的程式都跑完 清空了,就會開始逐一執行Event Queue中的任務,Queue是先進先出的資料結構,所以先進來的函式會先被執行。

這個過程是不斷循環的,所以這機制又稱為Event Loop。

範例動畫流程

動畫取自 JavaScript Visualized: Event Loop

  1. greet函式被調用,return 'Hello!',彈出Stack;
    respond函式被調用,return一個setTimeout

  2. 由於respond函式return了一個非同步行為(setTimeout),所以會把setTimeout轉交給Web Api處理,接著respond()彈出Stack

  3. 設定的1秒到了,添加到Event Queue裡

  4. 如果Stack為空,那麼Event Queue中的第一項將被添加到Stack

  5. 在Stack中return 'Hey',彈出Stack

簡單題目測試

這段程式輸出的結果是?

function test(){

  console.log('a')

  setTimeout(() => {
    console.log('b')
  }, 0)

  console.log('c')
}

test()

答:
a
c
b

因為b是一個非同步事件,他會被放到Event Queue裡,
也就是說,它在所有程式執行完(Stack清空)後才會執行,所以答案就是a->c->b

Reference:
https://www.youtube.com/watch?v=8aGhZQkoFbQ
https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif


#w3HexSchool #javascript #Event Loop #Event Queue







Related Posts

DNS, Lock, NoSQL vs SQL and ACID

DNS, Lock, NoSQL vs SQL and ACID

JavaScript 基礎筆記

JavaScript 基礎筆記

Elevate Your Dermatology Practice with the Electric Dermatology Chair

Elevate Your Dermatology Practice with the Electric Dermatology Chair


Comments